home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / OTPCX.ZIP / pcxload.doc < prev    next >
Text File  |  1996-05-14  |  8KB  |  193 lines

  1.  
  2.                       - THE OUTLAW TRIAD DEMO-SERIES -
  3.  
  4. ────────────────────────────────■ PART V ■────────────────────────────────────
  5.  
  6.                          Written by : Vulture/OT
  7.                          Code in    : Pascal/asm
  8.                          Topic      : Decoding .pcx files
  9.  
  10. ──────────────────────────────■ Introduction ■────────────────────────────────
  11.  
  12.  Welcome to the Outlaw Triad demo-series! In these series we will be talking
  13.  about programming demo-effects in either pascal or assembler. Theory behind
  14.  the effects shall be discussed while a full sourcecode is also provided.
  15.  We have reached the fifth release in these series already. This time we will
  16.  talk about decoding .pcx files. This is a very wellknown graphics format and
  17.  very easy to use, once you know the trick. A full pcx-decoding routine coded
  18.  in Pascal is provided. Enjoy!
  19.  
  20. ─────────────────────────────────■ Theory ■───────────────────────────────────
  21.  
  22.  Note: we will discuss how to decode a .pcx file in plain mode 13h. This will
  23.        not work in any unchained mode or high resolution modes.
  24.  
  25.  Ok, let's get right down to business and start with looking at the actual
  26.  format of a .pcx file. Here it is:
  27.  
  28.    - Header     (128 bytes)
  29.    - Data part
  30.    - Palette    (768 bytes)
  31.  
  32.  Now, usually we can just ignore the header when we know we want to display
  33.  a picture in plain mode 13h. Anyhow, for those of you who want to know how
  34.  the header looks like, I'll type it down:
  35.  
  36.    0  Manufacturer
  37.    1  Version
  38.    2  Encoding
  39.    3  Bits Per Pixel
  40.    4  XMin, Ymin, XMax, YMax (2 bytes each)
  41.    12 Horizontal Resolution (2 bytes)
  42.    14 Verticle Resolution (2 bytes)
  43.    16 Color pallette setting (48 bytes)
  44.    64 Reserved
  45.    65 Number of color planes
  46.    66 Bytes per line (2 bytes)
  47.    68 1 = Color    2 = Grayscale (2 bytes)
  48.    70 Blank (58 bytes)
  49.  
  50.  That's it. This adds up to 128 bytes.
  51.  
  52.  Ok, as you can see from the format, the palette data is situated right at
  53.  the end of the .pcx file. It's usually best to set the palette of the .pcx
  54.  file before you write the file to the screen. To set the palette, you could
  55.  do something like this:
  56.  
  57.    - Seek to (end of file - 768)
  58.    - Grab values
  59.    - Divide all by 4
  60.    - Send to vga
  61.  
  62.  Vga RGB values range 0..63 while the RGB values in the .pcx file are 0..255.
  63.  To get the correct vga values, we divide by 4. In the sourcecode I grabbed
  64.  all 768 RGB values at once. I've set the colors using a standard SetColor
  65.  procedure. Easy stuff, once you know what to do...
  66.  
  67.  Ok, now let's start decoding, shall we? (ignore header, seek to 128th byte)
  68.  
  69.  We read a byte from the data. If the top 2 bits of the byte aren't set,
  70.  the byte can be written to the screen. If they ARE set, we go into a loop
  71.  in which we process the next byte. In pascalcode:
  72.  
  73.  Temp := (read first byte from data)
  74.  If ((Temp AND 192) = 192) then         { Top 2 bits set? (192 = 11000000b) }
  75.  Begin                                  { If so, then go write next byte }
  76.    Temp2 := (read next byte from data)
  77.    For Loop := 1 to (Temp AND 63) Do    { Set loopcounter (63 = 00111111b) }
  78.    Begin                                { Write next byte a number of times }
  79.      SetPixel(VgaPos,Temp2);
  80.      Inc(VgaPos);
  81.    End;
  82.  End
  83.  Else                                   { Top bits not set, plot first byte }
  84.  Begin
  85.    SetPixel(VgaPos,Temp);               { Temp = color }
  86.    Inc(VgaPos);
  87.  End;
  88.  
  89.  So, what does all this mean? Well, like stated previously, first we see
  90.  if the top 2 bits of the FIRST byte we read are set. If the top 2 bits
  91.  are set, we go and write the NEXT byte to the screen. The number of times
  92.  we write the next byte to the screen is determined by ANDing the FIRST byte
  93.  with 63. If the top two bits of the first byte aren't set, we simply write
  94.  the first byte to the screen. That's all there is to it! In steps:
  95.  
  96.      - 1. Read a byte
  97.      - 2. Check if top 2 bits of that byte are set
  98.      - 3. If they are set, go to 5
  99.      - 4. Top 2 bits aren't set, write the byte to the screen (and back to 1)
  100.      - 5. Determine loopcounter by 'and'ing the byte with 00111111b (63)
  101.      - 6. Read next byte
  102.      - 7. Write that byte to the screen a number of times (then back to 1)
  103.  
  104.  Pretty easy once you get the point...
  105.  
  106.  For those of you who don't know much about assembler and the 'AND' command,
  107.  I will spend a few bytes extra... If you 'and' a bit with 0, that bit will
  108.  get the value 0. An example:
  109.  
  110.   (original byte)    10101010b
  111.   ('anding' byte)    01000001b
  112.                      ---------
  113.   (resulting byte)   00000000b
  114.  
  115.  You see? So with the 'AND' command you can disable certain bits in a byte!
  116.  Now what happens when we 'and' a bit with 1? In that case, the bit will keep
  117.  it's origal value. An example:
  118.  
  119.   (original byte)    01010101b
  120.   ('anding' byte)    10111110b
  121.                      ---------
  122.   (resulting byte)   00010100b
  123.  
  124.  Get it? I know this all might sound pretty damn cryptic if you are new to
  125.  this. Just go and read a book on assembler and practise a lot. And remember
  126.  these two things:
  127.  
  128.    - a bit 'anded' with 0, will be 0
  129.    - a bit 'anded' with 1, will keep it's original value (0 or 1)
  130.  
  131.  When you keep this in mind, the pcxdecoder is a piece of cake. Just do some
  132.  experimenting and you'll get it eventually. Trial and error rulez... ;-)
  133.  
  134.  The routine provided here to decode a pcxfile is very slow. However, you
  135.  can speed it up by using more assembler code. Also, you should implement
  136.  code to write the pcx file to another destination besides the VGA screen,
  137.  like a virtual page. Hint: load the pcx into memory at once. Don't read
  138.  data byte per byte from disk. That's very slow. And remember, this is only
  139.  an example. I can give you my own routines, but I feel that people should
  140.  learn for themselves and not just use code they found somewhere. However,
  141.  if you really want more code, write me and I'll send 'm to you. Oh, if you
  142.  find this stuff usefull, a mention in your own productions is appriciated.
  143.  Having problems? Mail me! I'd like to hear from you!
  144.  
  145.  Ok, this is all for now. Happy coding!
  146.  
  147.        - Vulture / Outlaw Triad -
  148.  
  149. ───────────────────────────────■ Distro Sites ■───────────────────────────────
  150.  
  151.  Call our distrobution sites! All our releases are available at:
  152.  
  153.   BlueNose      World HQ          +31 (0)345-619401
  154.   FireHouse     Distrosite        +31 (0)528-274176
  155.   The Force     Distrosite        +31 (0)36-5346967    More distros wanted!
  156.   Bugs'R'Us     Distrosite        +31 (0)252-686092    (preferably outside
  157.   MagicWare     Italian HQ        +39  6-52355532       of The Netherlands)
  158.   ShockWave     South African HQ  +27 (011)888-6345
  159.  
  160.  Also check the major FTP sites for Outlaw Triad productions.
  161.  
  162. ──────────────────────────────────■ Contact ■─────────────────────────────────
  163.  
  164.  Want to contact Outlaw Triad for some reason? You can reach us at our
  165.  distrosites in Holland. Or if you have e-mail access, mail us:
  166.  
  167.    Vulture   (coder/pr)   comma400@tem.nhl.nl
  168.  
  169.  Our internet homepage:
  170.  
  171.    http://www.tem.nhl.nl/~comma400/vulture.html
  172.  
  173.  These internet adresses should be valid at least till june 1996.
  174.  
  175. ──────────────────────────────────────────────────────────────────────────────
  176.  
  177. Quote:  There are 3 types of persons: those who can count and those who can't!
  178.  
  179.  
  180.  
  181.  
  182.  
  183. ──────────────────────────────────────────────────────────────────────────────
  184.  Note for those of you who read part 4 of these series...
  185.  
  186.  I removed a small but annoying bug from the source code. Before writing a
  187.  characters scanline, you must READ the byte from the vga position you are
  188.  planning to write to. This will load the latches and readies the vga for
  189.  your WRITE command. I forgot to do this in the source which resulted into
  190.  incorrect characters (e.g. white background) when you run the program.
  191.  Anyway, this is what you got to implement. Shouldn't be too hard...
  192. ──────────────────────────────────────────────────────────────────────────────
  193.